Skip to content

[Feature] [A11y Bug] Dark Mode for Webclipper#662

Open
aanchalbhansali with Copilot wants to merge 5 commits into
masterfrom
copilot/a11y-onenoe-clipper-verify-accessibility-dark-mode
Open

[Feature] [A11y Bug] Dark Mode for Webclipper#662
aanchalbhansali with Copilot wants to merge 5 commits into
masterfrom
copilot/a11y-onenoe-clipper-verify-accessibility-dark-mode

Conversation

Copilot AI commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

The Web Clipper popup stayed on a light theme even when the OS/browser was in dark mode, making the clipper UI visually inconsistent and harder to use for low-vision users. This change updates the popup to follow the system dark theme while preserving the existing light theme and forced-colors behavior.

  • Theme tokenization

    • Moved popup surface, text, border, scrollbar, and state colors onto CSS variables in renderer.less.
    • Added a prefers-color-scheme: dark token set so the existing UI picks up dark values.
    • Made status icons theme-aware so success and error states stay visible on dark surfaces.
  • Dark mode surface updates

    • Switched popup chrome from hard-coded light colors to theme-aware values for:
      • sidebar/background surfaces
      • preview container/frame chrome
      • dropdown flyout shadow/borders
      • error and warning states
      • dark-mode scrollbar thumb contrast
  • Asset and control adjustments

    • Made theme-sensitive assets and controls render correctly in dark mode by updating:
      • section picker chevron color
      • PDF mode icon filter
      • region remove button/icon treatment
      • primary button foreground handling
      • selected/active brand foreground contrast
  • Preview rendering updates

    • Updated the article and bookmark preview iframe CSS injection to reuse the shared themed scrollbar thumb color so preview scrollbars remain visible in dark mode.
  • Scope

    • Kept the change localized to src/styles/renderer.less and the preview styling logic in src/scripts/renderer.ts; no broader renderer flow or capture behavior changed.
:root {
  --colorNeutralBackground1: #ffffff;
  --colorNeutralForeground1: #242424;
}

@media (prefers-color-scheme: dark) {
  :root {
    --colorNeutralBackground1: #292929;
    --colorNeutralForeground1: #ffffff;
    --colorBrandForeground1: #c9a3ff;
    --scrollbarThumbColor: rgba(255,255,255,0.4);
  }
}

#sidebar {
  background: var(--colorNeutralBackground1);
  color: var(--colorNeutralForeground1);
}

Images:

Work item: AB#8785003
Created via Azure DevOps

Copilot AI changed the title [WIP] Verify accessibility of OneNote Clipper in dark mode Adopt system dark mode in the Web Clipper popup Jun 9, 2026
Copilot AI requested a review from aanchalbhansali June 9, 2026 19:50
@aanchalbhansali

Copy link
Copy Markdown
Contributor

@copilot These preview buttons in the "Article" mode are not visible as of now:
image

Copilot AI commented Jul 3, 2026

Copy link
Copy Markdown
Contributor Author

@copilot These preview buttons in the "Article" mode are not visible as of now:
<img width="303" height="56" alt="image" src="https://github.com/user-attachments/assets/41b81372-4fcc-4aa7-ae19-ff5b22...

Fixed in aa88ff4. The Article toolbar’s highlight and font-size SVGs now use theme-aware colors so they stay visible in dark mode.

@aanchalbhansali aanchalbhansali changed the title Adopt system dark mode in the Web Clipper popup [Feature] [A11y Bug] Dark Mode for Webclipper Jul 3, 2026
@aanchalbhansali aanchalbhansali marked this pull request as ready for review July 3, 2026 15:09
@aanchalbhansali aanchalbhansali requested a review from wikirby July 3, 2026 15:23
@wikirby

wikirby commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

TL;DR: Dark-mode tokenization is solid (surfaces/text/forced-colors all look right). Two visibility items on the dark surfaces: (1) the brand-purple text/controls read too faint — worth a dark-only lighter shade; (2) the dark-mode scrollbar is hard to see. Detail below.


Really nice work on this — moving the surface/text/border/state colors onto themeable CSS variables with a prefers-color-scheme set is a clean approach, and the forced-colors path looks well preserved. I pulled the branch, built it clean, and side-loaded to look it over.

1. Brand-purple text is hard to read in dark mode. The purple (#7719AA) is kept the same in both themes, and where it's a foreground — selected mode button ("Article"), active font/highlighter toggles, selected Location dropdown item, keyboard focus ring, and the capture/save progress fill — it's very low-contrast on the dark background. Was keeping the brand color constant across themes deliberate? Fluent 2's dark theme lightens its brand foreground tokens for exactly this, and its accessibility guidance calls for 4.5:1 text / 3:1 interactive elements. Would a dark-only lighter shade fit the token setup you've built? These all resolve to the one @colorCompoundBrandBackground token, so they'd likely improve together. (The Clip button is fine — white on purple reads well.) Small related thing: the selected mode icon filter isn't overridden in the dark block, so it stays purple like the text.

2. The dark-mode scrollbar is hard to see. The thumb blends into the dark surface enough that it's easy to miss there's more to scroll. The light-mode scrollbar reads fine, so this looks specific to the new dark thumb value — nudging it to a more visible shade would help.

Happy to be missing context on the brand-color decision — mostly want to understand the reasoning before it ships. Thanks again for taking this on!

@wikirby

wikirby commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

TL;DR: Curious about the dark-mode surface-elevation direction — the PR's neutral backgrounds get lighter as they recede, which is the opposite of Fluent's shipped dark neutrals. Not a contrast issue (all surfaces pass), and not something I'd gate on — just want to understand the intent.


One design-consistency question I wanted to raise separately from the a11y items, since it's subjective rather than a contrast problem. The dark neutral ramp goes:

  • This PR: base #1f1f1f -> #262626 -> #2b2b2b — i.e. surfaces get lighter as the index rises.
  • Fluent's shipped dark neutral tokens (colorNeutralBackground1/2/3 in the fluentui token source): #292929 -> #1f1f1f -> #141414 — surfaces get darker/more recessed as the index rises.

So the direction is inverted relative to Fluent's defaults, and the base surface is also a step darker than Fluent's Background1. To be clear on grounding: I could only find this as a divergence from the shipped token values — the Fluent 2 design site itself expresses elevation through shadow, and its neutral guidance is only qualitative ("use lighter neutrals to highlight areas of primary focus"), so I'm not claiming a published rule is broken here.

Was the lighter-as-it-recedes direction a deliberate choice — e.g. because the clipper is a flat two-surface layout where Fluent's elevation semantics don't map cleanly? Or were these hand-picked, in which case would matching Fluent's shipped dark neutrals be worth it for cross-product consistency? Genuinely asking — you may have context on the layout intent that I'm missing.

@aanchalbhansali

Copy link
Copy Markdown
Contributor

1. Brand-purple text is hard to read in dark mode. The purple (#7719AA) is kept the same in both themes, and where it's a foreground — selected mode button ("Article"), active font/highlighter toggles, selected Location dropdown item, keyboard focus ring, and the capture/save progress fill — it's very low-contrast on the dark background. Was keeping the brand color constant across themes deliberate? Fluent 2's dark theme lightens its brand foreground tokens for exactly this, and its accessibility guidance calls for 4.5:1 text / 3:1 interactive elements. Would a dark-only lighter shade fit the token setup you've built? These all resolve to the one @colorCompoundBrandBackground token, so they'd likely improve together. (The Clip button is fine — white on purple reads well.) Small related thing: the selected mode icon filter isn't overridden in the dark block, so it stays purple like the text.

2. The dark-mode scrollbar is hard to see. The thumb blends into the dark surface enough that it's easy to miss there's more to scroll. The light-mode scrollbar reads fine, so this looks specific to the new dark thumb value — nudging it to a more visible shade would help.

  1. One design-consistency question I wanted to raise separately from the a11y items, since it's subjective rather than a contrast problem. The dark neutral ramp goes:

This PR: base #1f1f1f -> #262626 -> #2b2b2b — i.e. surfaces get lighter as the index rises.
Fluent's shipped dark neutral tokens (colorNeutralBackground1/2/3 in the fluentui token source): #292929 -> #1f1f1f -> #141414 — surfaces get darker/more recessed as the index rises.
So the direction is inverted relative to Fluent's defaults, and the base surface is also a step darker than Fluent's Background1. To be clear on grounding: I could only find this as a divergence from the shipped token values — the Fluent 2 design site itself expresses elevation through shadow, and its neutral guidance is only qualitative ("use lighter neutrals to highlight areas of primary focus"), so I'm not claiming a published rule is broken here.

@copilot Please work on these issues.

Copilot AI commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

1. Brand-purple text is hard to read in dark mode. The purple (#7719AA) is kept the same in both themes, and where it's a foreground — selected mode button ("Article"), active font/highlig...

Addressed in 5dca3ca. Dark mode now uses a lighter brand foreground for selected/focused states, brightens the dark scrollbar thumb, adds a dark override for the selected PDF mode icon filter, and aligns the dark neutral ramp with Fluent’s shipped direction.

@wikirby

wikirby commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

TL;DR: The 5dca3ca fixes verify well — brand foreground, focus ring, and progress fill all clear their thresholds in dark now, and the ramp + selected-icon filter look right. While sideloading the dark build I ran into three more dark-mode spots, grouped below with tested values (ratios in parens).

1. Status icons keep their light-mode fills in dark (success + error). The check and error-circle SVGs bake in #0e700e / #c50f1f, which land at ~2.3–2.4:1 on the dark sidebar (#292929) — under the 3:1 non-text bar, so they blend in. There's already a dark --dangerForeground: #ff99a4 the error icon could reuse (~7:1), and a matching dark success green like #54b054 gets ~5.3:1. Making them themeable (same CSS-var pattern as --regionRemoveIcon) covers both at once.

2. The article/bookmark preview scrollbar stays on the light value in dark. The preview iframes inject their scrollbar separately (renderArticleHtml / renderBookmarkHtml), hardcoded to rgba(0,0,0,0.2). Since the iframe surface is --previewSurfaceBackground (#1a1a1a in dark), the black thumb is effectively invisible. Reusing --scrollbarThumbColor there matches the sidebar and shows in both themes.

3. Selected/active brand text is hard to read in dark. #b77bff clears AA on the numbers (~5.7:1), but it's genuinely tough on the eyes — saturated purple on near-black reads much lighter than its ratio implies, so the threshold undersells it. Lightening --colorBrandForeground1 in dark to #c9a3ff (~8:1) made a clear difference when I tested it — worth landing.

Happy to share the exact diffs if useful.

@aanchalbhansali

Copy link
Copy Markdown
Contributor

1. Status icons keep their light-mode fills in dark (success + error). The check and error-circle SVGs bake in #0e700e / #c50f1f, which land at ~2.3–2.4:1 on the dark sidebar (#292929) — under the 3:1 non-text bar, so they blend in. There's already a dark --dangerForeground: #ff99a4 the error icon could reuse (~7:1), and a matching dark success green like #54b054 gets ~5.3:1. Making them themeable (same CSS-var pattern as --regionRemoveIcon) covers both at once.

2. The article/bookmark preview scrollbar stays on the light value in dark. The preview iframes inject their scrollbar separately (renderArticleHtml / renderBookmarkHtml), hardcoded to rgba(0,0,0,0.2). Since the iframe surface is --previewSurfaceBackground (#1a1a1a in dark), the black thumb is effectively invisible. Reusing --scrollbarThumbColor there matches the sidebar and shows in both themes.

3. Selected/active brand text is hard to read in dark. #b77bff clears AA on the numbers (~5.7:1), but it's genuinely tough on the eyes — saturated purple on near-black reads much lighter than its ratio implies, so the threshold undersells it. Lightening --colorBrandForeground1 in dark to #c9a3ff (~8:1) made a clear difference when I tested it — worth landing.

@copilot Please work on these.

Copilot AI commented Jul 7, 2026

Copy link
Copy Markdown
Contributor Author

1. Status icons keep their light-mode fills in dark (success + error). The check and error-circle SVGs bake in #0e700e / #c50f1f, which land at ~2.3–2.4:1 on the dark sidebar (#292929) —...

Addressed in 0b58000. Dark mode now uses lighter active brand text, theme-aware success/error status icons, and the shared scrollbar thumb color inside the article and bookmark preview iframes.

@wikirby

wikirby commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Thanks for the thorough dark-mode work and the fast iteration.

Verified locally against 0b58000 (sideloaded + WCAG-checked): round-1 brand foreground / focus ring / progress fill all clear their thresholds, the neutral ramp matches Fluent's shipped dark tokens, and the selected-icon filter is live; round-2 status icons are now themeable (success ~5.3:1, error reuses --dangerForeground ~7:1), the preview scrollbar reuses --scrollbarThumbColor so it shows on the dark iframe surface, and the selected brand text is lightened to #c9a3ff (~8:1). Builds clean in dev and release. LGTM.

One small note: the screenshots in the PR description look like they predate these contrast changes — worth refreshing them so the description reflects the final dark-mode look?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants